home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / hdf / unix / hdf3_2r2.lha / HDF3.2r2 / src / dfgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-28  |  45.5 KB  |  1,360 lines

  1. /***************************************************************************
  2. *
  3. *
  4. *                         NCSA HDF version 3.2r2
  5. *                            October 30, 1992
  6. *
  7. * NCSA HDF Version 3.2 source code and documentation are in the public
  8. * domain.  Specifically, we give to the public domain all rights for future
  9. * licensing of the source code, all resale rights, and all publishing rights.
  10. *
  11. * We ask, but do not require, that the following message be included in all
  12. * derived works:
  13. *
  14. * Portions developed at the National Center for Supercomputing Applications at
  15. * the University of Illinois at Urbana-Champaign, in collaboration with the
  16. * Information Technology Institute of Singapore.
  17. *
  18. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  19. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  20. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  21. *
  22. ****************************************************************************
  23. */
  24.  
  25. #ifdef RCSID
  26. static char RcsId[] = "@(#)$Revision: 1.3 $";
  27. #endif
  28. /*
  29. $Header: /hdf/hdf/v3.2r2/src/RCS/dfgr.c,v 1.3 1992/10/23 00:14:11 koziol beta koziol $
  30.  
  31. $Log: dfgr.c,v $
  32.  * Revision 1.3  1992/10/23  00:14:11  koziol
  33.  * Changed all DFIstr*() and DFImem*() calls to HDstr*() and HDmem*() calls
  34.  * #ifdef'd out the macros Jason defined for Hopen, Hclose, etc. for Vsets
  35.  * Replaced Vset VFREESPACE and VGETSPACE calls with actual calls to HDfreespace
  36.  * and HDgetspace
  37.  * Added a MS-Windows lower lower for file I/O (which may not be completely working
  38.  *
  39.  * Revision 1.2  1992/10/12  18:11:51  koziol
  40.  * Updated for v3.2r2 release
  41.  *
  42.  * Revision 1.1  1992/08/25  21:40:44  koziol
  43.  * Initial revision
  44.  *
  45. */
  46. /*-----------------------------------------------------------------------------
  47.  * File:    dfgr.c
  48.  * Purpose: read and write general raster images
  49.  * Invokes: df.c, dfkit.c, dfcomp.c, dfgroup.c, dfgr.h
  50.  * Contents:
  51.  *  DFGRgetlutdims: get dimensions of lookup table
  52.  *  DFGRreqlutil: use this interlace when returning lookup table
  53.  *  DFGRgetlut: read in lookup table
  54.  *  DFGRgetimdims: get dimensions of image
  55.  *  DFGRreqimil: use this interlace when returning image
  56.  *  DFGRgetimage: read in image
  57.  *  DFGRsetcomp: specify compression scheme to be used
  58.  *  DFGRsetlutdims: set dimensions of lookup table
  59.  *  DFGRsetlut: set lookup table to write out with subsequent images
  60.  *  DFGRaddlut: write out lookup table
  61.  *  DFGRsetimdims: set dimensions of image
  62.  *  DFGRaddimage: write out image
  63.  *
  64.  *  DFGRgetrig: read in raster image group
  65.  *  DFGRaddrig: write out raster image group
  66.  *
  67.  *  DFGRIopen: open/reopen file
  68.  *  DFGRIriginfo: obtain info about next RIG
  69.  *  DFGRIgetdims: get dimensions of lut/iamge
  70.  *  DFGRIreqil: get lut/image with this interlace
  71.  *  DFGRIgetimlut: get image/lut
  72.  *  DFGRIsetdims: set image/lut dimensions
  73.  *  DFGRIaddimlut: write out image/lut
  74.  * Remarks: A RIG specifies attributes associated with an image - lookup table,
  75.  
  76.  *          dimension, compression, color compensation etc.
  77.  *---------------------------------------------------------------------------*/
  78.  
  79. #include "dfgr.h"
  80. #include "herr.h"
  81.  
  82. static char Grlastfile[DF_MAXFNLEN];
  83. static DFGRrig Grread;         /* information about RIG being read */
  84. static DFGRrig Grwrite;        /* information about RIG being written */
  85. static int Grnewdata = 0;      /* does Grread contain fresh data? */
  86. static int Grcompr = 0;        /* compression scheme to use */
  87. uint8  *Grlutdata=NULL;        /* points to lut, if in memory */
  88. static uint16 Grrefset=0;      /* Ref of image to get next */
  89. static uint16 Grlastref = 0;   /* Last ref read/written */
  90. static int Grreqil[2]= {0, 0}; /* requested lut/image il */
  91. static struct {                        /* track refs of set vals written before
  92.  */
  93.     int lut;                   /* -1: no vals set */
  94.     int16 dims[2];             /* 0: vals set, not written */
  95.     int nt;                    /* non-zero: ref of val in file */
  96. } Ref = {-1, {-1, -1}, -1 };
  97.  
  98. static DFGRrig Grzrig = {      /* empty RIG for initialization */
  99.     { {0, 0}, {0, 0}, {0, 0}, },
  100.     { {0, 0, {0, 0}, 0, 0, {0, 0}},
  101.       {0, 0, {0, 0}, 0, 0, {0, 0}},
  102.       {0, 0, {0, 0}, 0, 0, {0, 0}}, },
  103.     0, 0, (float32)0.0, (float32)0.0,
  104.     {(float32)0.0, (float32)0.0, (float32)0.0},
  105.     {(float32)0.0, (float32)0.0, (float32)0.0},
  106.     {(float32)0.0, (float32)0.0, (float32)0.0},
  107.     {(float32)0.0, (float32)0.0, (float32)0.0}, NULL
  108. };
  109.  
  110. uint8 GRtbuf[512];
  111.  
  112. #ifdef PERM_OUT
  113. #ifndef VMS
  114. int32 DFGRIopen();
  115. #else /*VMS*/
  116. int32 _DFGRIopen();
  117. #endif
  118. #endif
  119.  
  120. #define LUT     0
  121. #define IMAGE   1
  122.  
  123. /* private functions */
  124. #ifdef PROTOTYPE
  125. PRIVATE int32 DFGRIopen(char *filename, int access);
  126. PRIVATE int DFGRIriginfo(int32 file_id);
  127. PRIVATE int DFGRgetrig(int32 file_id, uint16 ref, DFGRrig *rig);
  128. PRIVATE int DFGRaddrig(int32 file_id, uint16 ref, DFGRrig *rig);
  129. #else
  130. PRIVATE int32 DFGRIopen();
  131. PRIVATE int DFGRIriginfo();
  132. PRIVATE int DFGRgetrig();
  133. PRIVATE int DFGRaddrig();
  134. #endif
  135.  
  136. /*-----------------------------------------------------------------------------
  137.  * Name:    DFGRgetlutdims
  138.  * Purpose: get dimensions of lut from next RIG
  139.  * Inputs:  filename: name of HDF file
  140.  *          pxdim, pydim: pointer to locations for returning x,y dimensions
  141.  *          pncomps: location for returning no of components
  142.  *          pil: location for returning interlace of lut in file
  143.  * Returns: 0 on success, -1 on failure with DFerror set
  144.  *          *pxdim, *pydim, *pncomps, *pil set on success
  145.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  146.  * Invokes: DFGRIgetdims
  147.  * Remarks: none
  148.  *---------------------------------------------------------------------------*/
  149.  
  150. #ifdef PROTOTYPE
  151. int DFGRgetlutdims(char *filename, int32 *pxdim, int32 *pydim, int *pncomps,
  152.                   int *pil)
  153. #else
  154. int DFGRgetlutdims(filename, pxdim, pydim, pncomps, pil)
  155. char *filename;
  156. int32 *pxdim, *pydim;
  157. int *pncomps, *pil;
  158. #endif
  159. {
  160.  
  161.     return(DFGRIgetdims(filename, pxdim, pydim, pncomps, pil, LUT));
  162. }
  163.  
  164.  
  165. /*-----------------------------------------------------------------------------
  166.  * Name:    DFGRreqlutil
  167.  * Purpose: get next lut with specified interlace
  168.  * Inputs:  il: interlace to get next lut with
  169.  * Returns: 0 on success, -1 on failure with DFerror set
  170.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  171.  * Invokes: DFGRIreqil
  172.  * Remarks: none
  173.  *---------------------------------------------------------------------------*/
  174.  
  175. #ifdef PROTOTYPE
  176. int DFGRreqlutil(int il)
  177. #else
  178. int DFGRreqlutil(il)
  179. int il;
  180. #endif
  181. {
  182.     return(DFGRIreqil(il, LUT));
  183. }
  184.  
  185.  
  186. /*-----------------------------------------------------------------------------
  187.  * Name:    DFGRgetlut
  188.  * Purpose: get lut from next RIG
  189.  * Inputs:  filename: name of HDF file
  190.  *          lut: pointer to space to return lookup table
  191.  *          xdim, ydim: dimensions of space to return lut
  192.  * Returns: 0 on success, -1 on failure with DFerror set
  193.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  194.  * Invokes: DFGRIgetimlut
  195.  * Remarks: space is assumed to be xdim * ydim * ncomps bytes
  196.  *---------------------------------------------------------------------------*/
  197.  
  198. #ifdef PROTOTYPE
  199. int DFGRgetlut(char *filename, VOIDP lut, int32 xdim, int32 ydim)
  200. #else
  201. int DFGRgetlut(filename, lut, xdim, ydim)
  202. char *filename;
  203. VOIDP lut;
  204. int32 xdim, ydim;
  205. #endif
  206. {
  207.  
  208.     /* 0 == C */
  209.     return(DFGRIgetimlut(filename, lut, xdim, ydim, LUT, 0));
  210. }
  211.  
  212. /*-----------------------------------------------------------------------------
  213.  * Name:    DFGRgetimdims
  214.  * Purpose: get dimensions of next image RIG
  215.  * Inputs:  filename: name of HDF file
  216.  *          pxdim, pydim: pointer to locations for returning x,y dimensions
  217.  *          pncomps: location for returning no of components
  218.  *          pil: location for returning interlace of image in file
  219.  * Returns: 0 on success, -1 on failure with DFerror set
  220.  *          *pxdim, *pydim, *pncomps, *pil set on success
  221.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  222.  * Invokes: DFGRIgetdims
  223.  * Remarks: none
  224.  *---------------------------------------------------------------------------*/
  225.  
  226. #ifdef PROTOTYPE
  227. int DFGRgetimdims(char *filename, int32 *pxdim, int32 *pydim, int *pncomps,
  228.                  int *pil)
  229. #else
  230. int DFGRgetimdims(filename, pxdim, pydim, pncomps, pil)
  231. char *filename;
  232. int32 *pxdim, *pydim;
  233. int *pncomps, *pil;
  234. #endif
  235. {
  236.     return(DFGRIgetdims(filename, pxdim, pydim, pncomps, pil, IMAGE));
  237. }
  238.  
  239. /*-----------------------------------------------------------------------------
  240.  * Name:    DFGRreqimil
  241.  * Purpose: get next image with specified interlace
  242.  * Inputs:  il: interlace to get next image with
  243.  * Returns: 0 on success, -1 on failure with DFerror set
  244.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  245.  * Invokes: DFGRIreqil
  246.  * Remarks: none
  247.  *---------------------------------------------------------------------------*/
  248.  
  249. #ifdef PROTOTYPE
  250. int DFGRreqimil(int il)
  251. #else
  252. int DFGRreqimil(il)
  253. int il;
  254. #endif
  255. {
  256.     return(DFGRIreqil(il, IMAGE));
  257. }
  258.  
  259. /*-----------------------------------------------------------------------------
  260.  * Name:    DFGRgetimage
  261.  * Purpose: get image from next RIG
  262.  * Inputs:  filename: name of HDF file
  263.  *          image: pointer to space to return image
  264.  *          xdim, ydim: dimensions of space to return lut
  265.  * Returns: 0 on success, -1 on failure with DFerror set
  266.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  267.  * Invokes: DFGRIgetimlut
  268.  * Remarks: space is assumed to be xdim * ydim * ncomps bytes
  269.  *---------------------------------------------------------------------------*/
  270.  
  271. #ifdef PROTOTYPE
  272. int DFGRgetimage(char *filename, VOIDP image, int32 xdim, int32 ydim)
  273. #else
  274. int DFGRgetimage(filename, image, xdim, ydim)
  275. char *filename;
  276. VOIDP image;
  277. int32 xdim, ydim;
  278. #endif
  279. {
  280.     /* 0 == C */
  281.     return(DFGRIgetimlut(filename, image, xdim, ydim, IMAGE, 0));
  282. }
  283.  
  284. /*-----------------------------------------------------------------------------
  285.  * Name:    DFGRsetcompress
  286.  * Purpose: set compression scheme to use
  287.  * Inputs:  scheme: compression scheme
  288.  * Returns: 0 on success, -1 on failure with DFerror set
  289.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  290.  * Invokes: none
  291.  * Remarks: none
  292.  *---------------------------------------------------------------------------*/
  293.  
  294. #ifdef PROTOTYPE
  295. int DFGRsetcompress(int scheme)
  296. #else
  297. int DFGRsetcompress(scheme)
  298. int scheme;
  299. #endif
  300. {
  301.     Grcompr = scheme;
  302.     return SUCCEED;
  303. }
  304.  
  305. /*-----------------------------------------------------------------------------
  306.  * Name:    DFGRsetlutdims
  307.  * Purpose: set dimensions of lut to write next
  308.  * Inputs:  xdim, ydim: dimensions of lut
  309.  *          ncomps: no of components
  310.  *          il: interlace of lut
  311.  * Returns: 0 on success, -1 on failure with DFerror set
  312.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  313.  * Invokes: DFGRIsetdims
  314.  * Remarks: none
  315.  *---------------------------------------------------------------------------*/
  316.  
  317. #ifdef PROTOTYPE
  318. int DFGRsetlutdims(int32 xdim, int32 ydim, int ncomps, int il)
  319. #else
  320. int DFGRsetlutdims(xdim, ydim, ncomps, il)
  321. int32 xdim, ydim;
  322. int ncomps, il;
  323. #endif
  324. {
  325.     if (DFGRIsetil(il, LUT) < 0) return FAIL;
  326.     return(DFGRIsetdims(xdim, ydim, ncomps, LUT));
  327. }
  328.  
  329.  
  330. /*-----------------------------------------------------------------------------
  331.  * Name:    DFGRsetlut
  332.  * Purpose: set lut for subsequent RIGs
  333.  * Inputs:  lut: lookup table to write
  334.  *          xdim, ydim: dimensions of array lut
  335.  * Returns: 0 on success, -1 on failure with DFerror set
  336.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  337.  * Invokes: DFGRIaddimlut
  338.  * Remarks: array lut is assumed to be xdim * ydim * ncomps bytes
  339.  *---------------------------------------------------------------------------*/
  340.  
  341. #ifdef PROTOTYPE
  342. int DFGRsetlut(VOIDP lut, int32 xdim, int32 ydim)
  343. #else
  344. int DFGRsetlut(lut, xdim, ydim)
  345. VOIDP lut;
  346. int32 xdim, ydim;
  347. #endif
  348. {
  349.     /* 0 == C, 0 == no newfile */
  350.     return(DFGRIaddimlut((char*)NULL, lut, xdim, ydim, LUT, 0, 0));
  351. }
  352.  
  353.  
  354. /*-----------------------------------------------------------------------------
  355.  * Name:    DFGRaddlut
  356.  * Purpose: write lut to file, associate it with subsequent RIGs
  357.  * Inputs:  filename: name of HDF file
  358.  *          lut: lookup table to write
  359.  *          xdim, ydim: dimensions of array lut
  360.  * Returns: 0 on success, -1 on failure with DFerror set
  361.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  362.  * Invokes: DFGRIaddimlut
  363.  * Remarks: array lut is assumed to be xdim * ydim * ncomps bytes
  364.  *---------------------------------------------------------------------------*/
  365.  
  366. #ifdef PROTOTYPE
  367. int DFGRaddlut(char *filename, VOIDP lut, int32 xdim, int32 ydim)
  368. #else
  369. int DFGRaddlut(filename, lut, xdim, ydim)
  370. char *filename;
  371. VOIDP lut;
  372. int32 xdim, ydim;
  373. #endif
  374. {
  375.     /* 0 == C, 0 == no new file */
  376.     return(DFGRIaddimlut(filename, lut, xdim, ydim, LUT, 0, 0));
  377. }
  378.  
  379.  
  380. /*-----------------------------------------------------------------------------
  381.  * Name:    DFGRsetimdims
  382.  * Purpose: set dimensions of image to write next
  383.  * Inputs:  xdim, ydim: dimensions of image
  384.  *          ncomps: no of components
  385.  *          il: interlace of image
  386.  * Returns: 0 on success, -1 on failure with DFerror set
  387.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  388.  * Invokes: DFGRIsetdims
  389.  * Remarks: none
  390.  *---------------------------------------------------------------------------*/
  391.  
  392. #ifdef PROTOTYPE
  393. int DFGRsetimdims(int32 xdim, int32 ydim, int ncomps, int il)
  394. #else
  395. int DFGRsetimdims(xdim, ydim, ncomps, il)
  396. int32 xdim, ydim;
  397. int ncomps, il;
  398. #endif
  399. {
  400.     if (DFGRIsetil(il, IMAGE) < 0) return FAIL;
  401.     return(DFGRIsetdims(xdim, ydim, ncomps, IMAGE));
  402. }
  403.  
  404. /*-----------------------------------------------------------------------------
  405.  * Name:    DFGRaddimage
  406.  * Purpose: Write out image
  407.  * Inputs:  filename: name of HDF file
  408.  *          image: image to write
  409.  *          xdim, ydim: dimensions of array image
  410.  * Returns: 0 on success, -1 on failure with DFerror set
  411.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  412.  * Invokes: DFGRIaddimlut
  413.  * Remarks: array image is assumed to be xdim * ydim * ncomps bytes
  414.  *---------------------------------------------------------------------------*/
  415.  
  416. #ifdef PROTOTYPE
  417. int DFGRaddimage(char *filename, VOIDP image, int32 xdim, int32 ydim)
  418. #else
  419. int DFGRaddimage(filename, image, xdim, ydim)
  420. char *filename;
  421. VOIDP image;
  422. int32 xdim, ydim;
  423. #endif
  424. {
  425.     /* 0 == C, 0 == not new file */
  426.     return(DFGRIaddimlut(filename, image, xdim, ydim, IMAGE, 0, 0));
  427. }
  428.  
  429. #ifdef PROTOTYPE
  430. int DFGRputimage(char *filename, VOIDP image, int32 xdim, int32 ydim)
  431. #else
  432. int DFGRputimage(filename, image, xdim, ydim)
  433. char *filename;
  434. VOIDP image;
  435. int32 xdim, ydim;
  436. #endif
  437. {
  438.     /* 0 == C, 1 == new file */
  439.     return(DFGRIaddimlut(filename, image, xdim, ydim, IMAGE, 0, 1));
  440. }
  441.  
  442. /*-----------------------------------------------------------------------------
  443.  * Name:    DFGRreadref
  444.  * Purpose: Set ref of rig to get next
  445.  * Inputs:  filename: file to which this applies
  446.  *          ref: reference number of next get
  447.  * Returns: 0 on success, -1 on failure
  448.  * Users:   HDF programmers, other routines and utilities
  449.  * Invokes: DFGRIopen, DFIfind, DFclose
  450.  * Remarks: checks if rig with this ref exists
  451.  *---------------------------------------------------------------------------*/
  452.  
  453. #ifdef PROTOTYPE
  454. int DFGRreadref(char *filename, uint16 ref)
  455. #else
  456. int DFGRreadref(filename, ref)
  457.     char *filename;
  458.     uint16 ref;
  459. #endif
  460. {
  461.     int32 file_id;
  462.     int32 aid;
  463.  
  464.     HEclear();
  465.  
  466.     file_id = DFGRIopen(filename, DFACC_READ);
  467.     if (file_id == FAIL)
  468.        return FAIL;
  469.  
  470.     aid = Hstartread(file_id, DFTAG_RIG, ref);
  471.     if (aid == FAIL)
  472.         return(HDerr(file_id));
  473.     Hendaccess(aid);
  474.  
  475.     Grrefset = ref;
  476.     return(Hclose(file_id));
  477. }
  478.  
  479.  
  480. /*****************************************************************************/
  481. /* This is the next lower layer - procedures to read in and write out a RIG. */
  482. /*****************************************************************************/
  483.  
  484. /*-----------------------------------------------------------------------------
  485.  * Name:    DFGRgetrig
  486.  * Purpose: Read a RIG into memory
  487.  * Inputs:  file_id: pointer to HDF file containing RIG
  488.  *          ref: reference number of RIG to get
  489.  *          rig: struct in which to place info obtained
  490.  * Returns: 0 on success, -1 on failure with DFerror set
  491.  *          contents of RIG in the struct rig
  492.  * Users:   HDF programmers, utilities, DFGRIgetdims,DFGRIgetimlut,
  493.  *          other routines
  494.  * Invokes: DFdiget, DFdinext, DFIcheck, DFgetelement
  495.  * Remarks: incomplete - does not support DFTAG_MA etc.
  496.  *---------------------------------------------------------------------------*/
  497.  
  498. #ifdef PROTOTYPE
  499. PRIVATE int DFGRgetrig(int32 file_id, uint16 ref, DFGRrig *rig)
  500. #else
  501. PRIVATE int DFGRgetrig(file_id, ref, rig)
  502.     int32 file_id;
  503.     uint16 ref;
  504.     DFGRrig *rig;
  505. #endif
  506. {
  507.     char *FUNC="DFGRgetrig";
  508.     uint16 elt_tag, elt_ref;
  509.     uint8 ntstring[4];
  510.     int type;
  511.  
  512.     HEclear();
  513.     if (!HDvalidfid(file_id) || !ref) {
  514.        HERROR(DFE_ARGS);
  515.         return FAIL;
  516.     }
  517.  
  518.     if (DFdiread(file_id, DFTAG_RIG, ref) == FAIL) /* read RIG into memory */
  519.         return FAIL;
  520.  
  521.     *rig = Grzrig;             /* fill rig with zeroes */
  522.     while (!DFdiget(&elt_tag, &elt_ref)) {     /* get next tag/ref from RIG */
  523.         switch (elt_tag) {     /* process tag/ref */
  524.             case DFTAG_CI:
  525.             case DFTAG_RI:
  526.             case DFTAG_LUT:
  527.                 type = (elt_tag==DFTAG_LUT) ? LUT : IMAGE;
  528.                 rig->data[type].tag = elt_tag;
  529.                 rig->data[type].ref = elt_ref;
  530.                 break;
  531.             case DFTAG_ID:          /* read description info */
  532.             case DFTAG_LD:
  533.                 type = (elt_tag==DFTAG_LD) ? LUT : IMAGE;
  534.                if (Hgetelement(file_id, elt_tag, elt_ref, GRtbuf) != FAIL) {
  535.                     uint8 *p;
  536.                     p = GRtbuf;
  537.                     INT32DECODE(p, rig->datadesc[type].xdim);
  538.                     INT32DECODE(p, rig->datadesc[type].ydim);
  539.                     UINT16DECODE(p, rig->datadesc[type].nt.tag);
  540.                     UINT16DECODE(p, rig->datadesc[type].nt.ref);
  541.                     INT16DECODE(p, rig->datadesc[type].ncomponents);
  542.                     INT16DECODE(p, rig->datadesc[type].interlace);
  543.                     UINT16DECODE(p, rig->datadesc[type].compr.tag);
  544.                     UINT16DECODE(p, rig->datadesc[type].compr.ref);
  545.                 } else
  546.                    return FAIL;
  547.  
  548.                 if (rig->datadesc[type].nt.tag==0)
  549.                    break; /* old RIGs */
  550.  
  551.                /* read NT */
  552.                 if (Hgetelement(file_id, rig->datadesc[type].nt.tag,
  553.                                rig->datadesc[type].nt.ref, ntstring) == FAIL)
  554.                     return FAIL;
  555.                 if ((ntstring[2]!=8) || (ntstring[1]!=DFNT_UCHAR)) {
  556.                     HERROR(DFE_BADCALL);
  557.                     return FAIL;
  558.                 }
  559.                 break;
  560.             default:           /* ignore unknown tags */
  561.                 break;
  562.         }
  563.     }
  564.     return SUCCEED;
  565. }
  566.  
  567. /*-----------------------------------------------------------------------------
  568.  * Name:    DFGRaddrig
  569.  * Purpose: Write RIG struct out to HDF file
  570.  * Inputs:  file_id: HDF file pointer
  571.  *          ref: ref to write RIG with
  572.  *          rig: struct containing RIG info to write
  573.  * Returns: 0 on success, -1 on failure with DFerror set
  574.  * Users:   HDF programmers, utilities, DFGRIaddimlut, other routines
  575.  * Invokes: DFIcheck, DFdistart, DFdiadd, DFdiend, DFputelement
  576.  * Remarks: none
  577.  *---------------------------------------------------------------------------*/
  578.  
  579. #ifdef PROTOTYPE
  580. PRIVATE int DFGRaddrig(int32 file_id, uint16 ref, DFGRrig *rig)
  581. #else
  582. PRIVATE int DFGRaddrig(file_id, ref, rig)
  583.     int32 file_id;
  584.     uint16 ref;
  585.     DFGRrig *rig;
  586. #endif
  587. {
  588.     char *FUNC="DFGRaddrig";
  589.     uint8 ntstring[4];
  590.     int32 lutsize;
  591.  
  592.     HEclear();
  593.  
  594.     if (!HDvalidfid(file_id) || !ref) {
  595.        HERROR(DFE_ARGS);
  596.         return FAIL;
  597.     }
  598.  
  599.     if (Ref.nt<=0) {           /* if nt not previously written to file */
  600.                                /* construct and write out NT */
  601.         ntstring[0] = DFNT_VERSION; /* version */
  602.         ntstring[1] = DFNT_UCHAR; /* type */
  603.         ntstring[2] = 8;       /* width: RIG data is 8-bit chars */
  604.         ntstring[3] = DFNTC_BYTE; /* class: data are numeric values */
  605.         if (Hputelement(file_id, DFTAG_NT, ref,
  606.                        (uint8 *)ntstring, (int32) 4)  == FAIL)
  607.             return FAIL;
  608.         rig->datadesc[IMAGE].nt.tag = DFTAG_NT;
  609.         rig->datadesc[IMAGE].nt.ref = ref;
  610.         Ref.nt = ref;
  611.     }
  612.  
  613.     if (Ref.dims[IMAGE]==0) {
  614.         uint8 *p;
  615.         p = GRtbuf;
  616.         INT32ENCODE(p, rig->datadesc[IMAGE].xdim);
  617.         INT32ENCODE(p, rig->datadesc[IMAGE].ydim);
  618.         UINT16ENCODE(p, rig->datadesc[IMAGE].nt.tag);
  619.         UINT16ENCODE(p, rig->datadesc[IMAGE].nt.ref);
  620.         INT16ENCODE(p, rig->datadesc[IMAGE].ncomponents);
  621.         INT16ENCODE(p, rig->datadesc[IMAGE].interlace);
  622.         UINT16ENCODE(p, rig->datadesc[IMAGE].compr.tag);
  623.         UINT16ENCODE(p, rig->datadesc[IMAGE].compr.ref);
  624.         if (Hputelement(file_id, DFTAG_ID, ref,
  625.                        GRtbuf, (int32)(p-GRtbuf)) == FAIL)
  626.             return FAIL;
  627.  
  628.         Ref.dims[IMAGE] = ref;
  629.     }
  630.     if (!Ref.lut) {            /* associated lut not written to this file */
  631.         if (Grlutdata==NULL) { /* no lut associated */
  632.             HERROR(DFE_ARGS);
  633.             return FAIL;
  634.         }
  635.         lutsize = Grwrite.datadesc[LUT].xdim * Grwrite.datadesc[LUT].ydim *
  636.            Grwrite.datadesc[LUT].ncomponents;
  637.         if (Hputelement(file_id, DFTAG_LUT, ref,
  638.                        Grlutdata, (int32)lutsize) == FAIL)
  639.            return FAIL;
  640.         rig->data[LUT].tag = DFTAG_LUT;
  641.         rig->data[LUT].ref = ref;
  642.         Ref.lut = ref;
  643.     }
  644.  
  645.     if (Ref.dims[LUT]==0) {
  646.         uint8 *p;
  647.         p = GRtbuf;
  648.         INT32ENCODE(p, rig->datadesc[LUT].xdim);
  649.         INT32ENCODE(p, rig->datadesc[LUT].ydim);
  650.         UINT16ENCODE(p, rig->datadesc[LUT].nt.tag);
  651.         UINT16ENCODE(p, rig->datadesc[LUT].nt.ref);
  652.         INT16ENCODE(p, rig->datadesc[LUT].ncomponents);
  653.         INT16ENCODE(p, rig->datadesc[LUT].interlace);
  654.         UINT16ENCODE(p, rig->datadesc[LUT].compr.tag);
  655.         UINT16ENCODE(p, rig->datadesc[LUT].compr.ref);
  656.         if (Hputelement(file_id, DFTAG_LD, ref,
  657.                        GRtbuf, (int32)(p-GRtbuf)) == FAIL)
  658.             return FAIL;
  659.         Ref.dims[LUT] = ref;
  660.     }
  661.  
  662.     /* prepare to start writing rig */
  663.     /* ### NOTE: the parameter to this call may go away */
  664.     if (DFdisetup(10) == FAIL)
  665.        return FAIL; /* max 10 tag/refs in set */
  666.     /* add tag/ref to RIG - image description, image and lookup table */
  667.     if (DFdiput(DFTAG_ID,(uint16)Ref.dims[IMAGE]) == FAIL)
  668.        return FAIL;
  669.  
  670.     if (DFdiput(rig->data[IMAGE].tag, rig->data[IMAGE].ref) == FAIL)
  671.        return FAIL;
  672.  
  673.     if ((Ref.dims[LUT]>0)
  674.        && (DFdiput(DFTAG_LD, (uint16)Ref.dims[LUT]) == FAIL))
  675.        return FAIL;
  676.  
  677.     if ((Ref.lut>0)
  678.        && (DFdiput(rig->data[LUT].tag, rig->data[LUT].ref) == FAIL))
  679.        return FAIL;
  680.  
  681.     /* write out RIG */
  682.     return(DFdiwrite(file_id, DFTAG_RIG, ref));
  683. }
  684.  
  685. /*****************************************************************************/
  686. /*----------------------- Internal routines ---------------------------------*/
  687. /*****************************************************************************/
  688.  
  689.  
  690. /*-----------------------------------------------------------------------------
  691.  * Name:    DFGRIopen
  692.  * Purpose: open or reopen a file
  693.  * Inputs:  filename: name of file to open
  694.  *          access : access mode
  695.  * Returns: file pointer on success, NULL on failure with DFerror set
  696.  * Users:   HDF systems programmers, all the RIG routines
  697.  * Invokes: DFopen
  698.  * Remarks: This is a hook for someday providing more efficient ways to
  699.  *          reopen a file, to avoid re-reading all the headers
  700.  *---------------------------------------------------------------------------*/
  701.  
  702. #ifdef PROTOTYPE
  703. PRIVATE int32 DFGRIopen(char *filename, int access)
  704. #else
  705. PRIVATE int32 DFGRIopen(filename, access)
  706.     char *filename;
  707.     int access;
  708. #endif
  709. {
  710.     int32 file_id;
  711.  
  712.     file_id = Hopen(filename, access, 0);
  713.     if (file_id == FAIL) return FAIL;
  714.  
  715.     /* use reopen if same file as last time - more efficient */
  716.     if (HDstrncmp(Grlastfile,filename,DF_MAXFNLEN) || (access==DFACC_CREATE)) {
  717.        /* treat create as different file */
  718.         Grrefset = 0;          /* no ref to get set for this file */
  719.         Grnewdata = 0;
  720.         if (Ref.lut>0) Ref.lut = 0;
  721.         if (Grlutdata==NULL)
  722.            Ref.lut = (-1);     /* no LUT if not a "set" call */
  723.         if (Ref.dims[IMAGE]>0)
  724.            Ref.dims[IMAGE] = 0;
  725.         if (Ref.dims[LUT]>0)
  726.            Ref.dims[LUT] = 0;
  727.         if (Ref.nt>0)
  728.            Ref.nt = 0;
  729.         Grread = Grzrig;        /* no rigs read yet */
  730.     }
  731.  
  732.     HDstrncpy(Grlastfile, filename, DF_MAXFNLEN);
  733.     /* remember filename, so reopen may be used next time if same file */
  734.     return(file_id);
  735. }
  736.  
  737. /*-----------------------------------------------------------------------------
  738.  * Name:    DFGRIriginfo
  739.  * Purpose: Get information about next RIG in file
  740.  * Inputs:  file_id: pointer to DF file
  741.  * Returns: 0 on success, -1 on failure with DFerror set
  742.  * Users:   HDF systems programmers
  743.  * Invokes: DFIfind, DFgetelement, DFGRgetrig
  744.  * Remarks: if Grrefset set, gets image with that ref, if any
  745.  *---------------------------------------------------------------------------*/
  746.  
  747. #ifdef PROTOTYPE
  748. PRIVATE int DFGRIriginfo(int32 file_id)
  749. #else
  750. PRIVATE int DFGRIriginfo(file_id)
  751. int32 file_id;
  752. #endif
  753. {
  754.     int i, isfirst;
  755.     uint16 newref=0, newtag, gettag, getref, ref, dummy;
  756.     struct {
  757.         uint16 xdim;
  758.         uint16 ydim;
  759.     } r8dims;
  760.     char *p;
  761.     int32 aid;
  762.  
  763.     isfirst = (Grrefset!=0) || (Grread.data[IMAGE].ref==0);
  764.     getref = Grrefset;         /* ref if specified, else 0 */
  765.     Grrefset = 0;              /* no longer need to remember specified ref */
  766.     gettag = DFTAG_RIG;
  767.     for (i=0; i<4; i++) {      /* repeat for RIG, RI8, CI8, II8 */
  768.        if (isfirst) {
  769.            aid = Hstartread(file_id, gettag, getref);
  770.        } else {
  771.            aid = Hstartread(file_id, gettag, Grread.data[IMAGE].ref);
  772.            if ((aid != FAIL) &&
  773.                Hnextread(aid, gettag, getref, DF_CURRENT) == FAIL) {
  774.                Hendaccess(aid);
  775.                aid = FAIL;
  776.            }
  777.        }
  778.        if (aid == FAIL) {
  779.            /* not found */
  780.             if (gettag==DFTAG_RIG) { /* were looking for RIGs */
  781.                 if ((Grread.data[IMAGE].tag==DFTAG_RI) /* file has Rigs */
  782.                     || (Grread.data[IMAGE].tag==DFTAG_CI)) {
  783.                     return FAIL;       /* no more to return */
  784.                 }
  785.                 gettag = DFTAG_RI8; /* if no RIGs in file, look for RI8s */
  786.             }
  787.             else if ((gettag==DFTAG_II8) && (!newref)) { /* no RI8/CI8/II8 */
  788.                 return FAIL;
  789.             }
  790.             continue;          /* continue checking */
  791.         }
  792.        /* found */
  793.        HQuerytagref(aid, &dummy, &ref);
  794.        Hendaccess(aid);
  795.         if (!newref || (ref < newref)) { /* is it next one? */
  796.             newref = ref;      /* remember tag, ref */
  797.             newtag = gettag;
  798.         }
  799.         if (gettag==DFTAG_RI8)
  800.            gettag = DFTAG_CI8; /* check next */
  801.         else if (gettag==DFTAG_CI8)
  802.            gettag = DFTAG_II8;
  803.         else
  804.            break;              /* all checked, quit */
  805.     }
  806.  
  807.     if (newtag==DFTAG_RIG) {
  808.         if (DFGRgetrig(file_id, newref, &Grread) == FAIL)
  809.             return FAIL;
  810.     } else {
  811.         Grread.data[IMAGE].ref = newref;
  812.         Grread.data[IMAGE].tag = newtag;
  813.         if (newtag==DFTAG_CI8)
  814.            Grread.datadesc[IMAGE].compr.tag = DFTAG_RLE;
  815.         else if (newtag==DFTAG_II8)
  816.             Grread.datadesc[IMAGE].compr.tag = DFTAG_IMC;
  817.  
  818.         if (Hgetelement(file_id, DFTAG_ID8, newref, (uint8 *)&r8dims) == FAIL)
  819.             return FAIL;
  820.         p = (char *) &r8dims;
  821.         UINT16DECODE(p, Grread.datadesc[IMAGE].xdim);
  822.         UINT16DECODE(p, Grread.datadesc[IMAGE].ydim);
  823.  
  824.        aid = Hstartread(file_id, DFTAG_IP8, newref);
  825.         if (aid != FAIL) {
  826.             Grread.data[LUT].tag = DFTAG_IP8;
  827.             Grread.data[LUT].ref = newref;
  828.            Hendaccess(aid);
  829.         }
  830.         HEclear();     /* reset it, just in case! */
  831.     }
  832.  
  833.     /* if LUT dimensions not set, set default dimensions */
  834.     if (Grread.data[LUT].tag && Grread.datadesc[LUT].xdim==0) {
  835.         Grread.datadesc[LUT].xdim = 256;
  836.         Grread.datadesc[LUT].ydim = 1;
  837.         Grread.datadesc[LUT].ncomponents = 3;
  838.     }
  839.  
  840.     Grlastref = Grread.data[IMAGE].ref;        /* remember ref read */
  841.  
  842.     return SUCCEED;
  843. }
  844.  
  845. /*-----------------------------------------------------------------------------
  846.  * Name:    DFGRIgetdims
  847.  * Purpose: get dimensions of next image/lut from RIG
  848.  * Inputs:  filename: name of HDF file
  849.  *          pxdim, pxdim: pointer to locations for returning x,y dimensions
  850.  *          pncomps: location for returning no of components
  851.  *          pil: location for returning interlace of image/lut in file
  852.  *          type: LUT to get lut dims, IMAGE to get image dims
  853.  * Returns: 0 on success, -1 on failure with DFerror set
  854.  *          *pxdim, *pydim are set to dimensions of the next image on success
  855.  *          *pncomps, *pil set on success
  856.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  857.  * Invokes: DFGRIopen, DFclose, DFGRIriginfo, DFIerr
  858.  * Remarks: none
  859.  *---------------------------------------------------------------------------*/
  860.  
  861. #ifdef PROTOTYPE
  862. int DFGRIgetdims(char *filename, int32 *pxdim, int32 *pydim,
  863.                         int *pncomps, int *pil, int type)
  864. #else
  865. int DFGRIgetdims(filename, pxdim, pydim, pncomps, pil, type)
  866.     char *filename;
  867.     int32 *pxdim, *pydim;
  868.     int *pncomps, *pil, type;
  869. #endif
  870. {
  871.     char *FUNC="DFGRIgetdims";
  872.     int32 file_id;
  873.  
  874.     HEclear();
  875.  
  876.     file_id = DFGRIopen(filename, DFACC_READ);
  877.     if (file_id == FAIL)
  878.        return FAIL;
  879.  
  880.     if (type==IMAGE) {         /* getimdims sequences, getlutdims does not */
  881.         if (DFGRIriginfo(file_id)
  882.            == FAIL)            /* reads next RIG or RI8 from file */
  883.             return(HDerr(file_id)); /* on error, close file and return -1 */
  884.         Grnewdata = 1;
  885.     }
  886.  
  887.     if (type==LUT && Grread.data[LUT].ref==0) {
  888.             HERROR(DFE_NOMATCH);
  889.             return HDerr(file_id);             /* no LUT */
  890.     }
  891.     if (pxdim)
  892.        *pxdim = Grread.datadesc[type].xdim;
  893.     if (pydim)
  894.        *pydim = Grread.datadesc[type].ydim;
  895.     if (pncomps)
  896.        *pncomps = Grread.datadesc[type].ncomponents;
  897.     if (pil)
  898.        *pil = Grread.datadesc[type].interlace;
  899.     return(Hclose(file_id));
  900. }
  901.  
  902. /*-----------------------------------------------------------------------------
  903.  * Name:    DFGRIreqil
  904.  * Purpose: set interlace with which to get subsequent images/luts
  905.  * Inputs:  il: interlace to get image/lut with
  906.  *          type: LUT for luts, IMAGE for images
  907.  * Returns: 0 on success, -1 on failure with DFerror set
  908.  * Users:   HDF users, utilities, other routines
  909.  * Invokes: none
  910.  * Remarks: none
  911.  *---------------------------------------------------------------------------*/
  912.  
  913. #ifdef PROTOTYPE
  914. int DFGRIreqil(int il, int type)
  915. #else
  916. int DFGRIreqil(il, type)
  917.     int il, type;
  918. #endif
  919. {
  920.     HEclear();
  921.  
  922.     Grreqil[type] = il;
  923.  
  924.     return SUCCEED;
  925. }
  926.  
  927.  
  928. /*-----------------------------------------------------------------------------
  929.  * Name:    DFGRIgetimlut
  930.  * Purpose: get next image/lut from a RIG
  931.  * Inputs:  filename: name of HDF file
  932.  *          imlut: space to read image/lut into
  933.  *          xdim, ydim: dimensions of space allocated by user for image/lut
  934.  *          type: LUT for luts, IMAGE for images
  935.  *          isfortran: 0 if called from C, 1 if called from Fortran
  936.  * Returns: 0 on success, -1 on failure with DFerror set
  937.  *          image/lut in imlut
  938.  * Users:   HDF HLL users, utilities, other routines
  939.  * Invokes: DFGRIopen, DFGRIriginfo, DFIerr, DFclose, DFgetelement, DFgetcomp
  940.  * Remarks: Will also get RI8s and CI8s if no RIGs in file
  941.  *          Normally, DFGRgetimdims is called first and it moves to next image
  942.  *          But if that is not called, DFGRgetimlut will itself move to next
  943.  *          image (but not next lut!).
  944.  *          Automatically decompresses images/luts
  945.  *---------------------------------------------------------------------------*/
  946.  
  947. /* shut lint up */
  948. /* ARGSUSED */
  949. #ifdef PROTOTYPE
  950. int DFGRIgetimlut(char *filename, VOIDP imlut, int32 xdim, int32 ydim,
  951.                          int type, int isfortran)
  952. #else
  953. int DFGRIgetimlut(filename, imlut, xdim, ydim, type, isfortran)
  954.     char *filename;
  955.     int32 xdim, ydim;
  956.     VOIDP imlut;
  957.     int type, isfortran;
  958. #endif
  959. {
  960.     char *FUNC="DFGRIgetimlut";
  961.     int32 file_id;
  962.     int32 currpos[3], currmax[3], destsize[3], bufsize, i, j;
  963.     uint8 *buf, *destp;
  964.     int32 aid;
  965.  
  966.     HEclear();
  967.  
  968.     file_id = DFGRIopen(filename, DFACC_READ);
  969.     if (file_id == FAIL)
  970.        return FAIL;
  971.  
  972.     if ((type==IMAGE) && (Grnewdata!=1)) { /* if Grread not fresh */
  973.         if (DFGRIriginfo(file_id)
  974.            == FAIL) /* reads next RIG or RI8 from file */
  975.             return(HDerr(file_id)); /* on error, close file and return -1 */
  976.     }
  977.     if (Grnewdata==0) {
  978.         HERROR(DFE_BADCALL);
  979.         return FAIL;
  980.     }
  981.     Grnewdata = 0;             /* read new RIG next time */
  982.  
  983.     if ((xdim!=Grread.datadesc[type].xdim)
  984.        || (ydim!=Grread.datadesc[type].ydim)) {
  985.         HERROR(DFE_ARGS);
  986.         return FAIL;
  987.     }
  988.  
  989.     /* read image/lut */
  990.     if (Grread.datadesc[type].compr.tag) { /* compressed image/lut */
  991.         if ((Grreqil[type] >= 0) &&
  992.            (Grreqil[type] != Grread.datadesc[type].interlace)) {
  993.             HERROR(DFE_UNSUPPORTED);
  994.             return FAIL;
  995.         }
  996.         if (DFgetcomp(file_id, Grread.data[type].tag, Grread.data[type].ref,
  997.                      (uint8*)imlut, Grread.datadesc[type].xdim,
  998.                      Grread.datadesc[type].ydim,
  999.                      Grread.datadesc[type].compr.tag) == FAIL)
  1000.             return(HDerr(file_id));
  1001.     } else {                   /* non-compressed raster image/lut */
  1002.         if (Grreqil[type]>=0) {
  1003.             if (Grreqil[type]>=Grread.datadesc[type].ncomponents) {
  1004.                 HERROR(DFE_ARGS);
  1005.                 return FAIL;
  1006.             }
  1007.             else if (Grreqil[type]!=Grread.datadesc[type].interlace) {
  1008.                aid = Hstartread(file_id, Grread.data[type].tag,
  1009.                                 Grread.data[type].ref);
  1010.                 if (aid == FAIL)
  1011.                     return(HDerr(file_id));
  1012.                /* current position in data */
  1013.                 currpos[0] = currpos[1] = currpos[2] = 0;
  1014.                 currmax[0] = Grread.datadesc[type].ncomponents;
  1015.                 currmax[1] = Grread.datadesc[type].xdim;
  1016.                 currmax[2] = Grread.datadesc[type].ydim;
  1017.  
  1018.                /* compute size of each dim of dest array */
  1019.                 destsize[0] = destsize[1] = 1;
  1020.                 destsize[2] = currmax[1]; /* xdim is more sig than ydim */
  1021.                 if (Grreqil[type]==0) {
  1022.                     destsize[1] *= currmax[0];
  1023.                     destsize[2] *= currmax[0];
  1024.                 }
  1025.                 else if (Grreqil[type]==1) {
  1026.                     destsize[0] *= currmax[1];
  1027.                     destsize[2] *= currmax[0];
  1028.                 }
  1029.                 else if (Grreqil[type]==2) {
  1030.                     destsize[0] *= currmax[1] * currmax[2];
  1031.                 }
  1032.  
  1033.                 bufsize = Grread.datadesc[type].ydim *
  1034.                    Grread.datadesc[type].ncomponents;
  1035.                 buf = (uint8 *)HDgetspace((uint32)bufsize);
  1036.                 if (buf==NULL) {
  1037.                    Hendaccess(aid);
  1038.                    return(HDerr(file_id));
  1039.                 }
  1040.  
  1041.                /* read byte by byte and copy */
  1042.                 for (i=0; i<Grread.datadesc[type].xdim; i++) {
  1043.                     if (Hread(aid, bufsize, buf) == FAIL) {
  1044.                        Hendaccess(aid);
  1045.                        return(HDerr(file_id));
  1046.                     }
  1047.                     for (j=0; j<bufsize; j++) {
  1048.                         destp =  (uint8 *) imlut + destsize[0] * currpos[0] +
  1049.                                                    destsize[1] * currpos[1] +
  1050.                                                    destsize[2] * currpos[2];
  1051.                         *destp = buf[j];
  1052.                         if (Grread.datadesc[type].interlace==0) {
  1053.                             if (++currpos[0] == currmax[0]) {
  1054.                                 currpos[0] = 0;
  1055.                                 if (++currpos[1] == currmax[1]) {
  1056.                                     currpos[1] = 0;
  1057.                                     if (++currpos[2] == currmax[2]) break;
  1058.                                 }
  1059.                             }
  1060.                         } else if (++currpos[1]==currmax[1]) {
  1061.                             currpos[1] = 0;
  1062.                             if (Grread.datadesc[type].interlace==1) {
  1063.                                 if (++currpos[0] == currmax[0]) {
  1064.                                     currpos[0] = 0;
  1065.                                     if (++currpos[2] == currmax[2]) break;
  1066.                                 }
  1067.                             } else {
  1068.                                 if (++currpos[2] == currmax[2]) {
  1069.                                     currpos[2] = 0;
  1070.                                     if (++currpos[0] == currmax[0]) break;
  1071.                                 }
  1072.                             }
  1073.                         }
  1074.                     }
  1075.                 }
  1076.                Hendaccess(aid);
  1077.                 return(Hclose(file_id));
  1078.             }
  1079.         }
  1080.         if (Hgetelement(file_id, Grread.data[type].tag, Grread.data[type].ref,
  1081.                        (uint8 *)imlut) == FAIL)
  1082.             return(HDerr(file_id));
  1083.     }
  1084.  
  1085.     return(Hclose(file_id));
  1086. }
  1087.  
  1088. /*-----------------------------------------------------------------------------
  1089.  * Name:    DFGRIsetdims
  1090.  * Purpose: set dimensions of image/lut
  1091.  * Inputs:  xdim, ydim: dimensions of lut
  1092.  *          ncomps: no of components
  1093.  *          il: interlace of lut
  1094.  *          type: LUT if lut, IMAGE if image
  1095.  * Returns: 0 on success, -1 on failure with DFerror set
  1096.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  1097.  * Invokes: none
  1098.  * Remarks: none
  1099.  *---------------------------------------------------------------------------*/
  1100.  
  1101. #ifdef PROTOTYPE
  1102. int DFGRIsetdims(int32 xdim, int32 ydim, int ncomps, int type)
  1103. #else
  1104. int DFGRIsetdims(xdim, ydim, ncomps, type)
  1105.     int32 xdim, ydim;
  1106.     int ncomps;
  1107.     int type;
  1108. #endif
  1109. {
  1110.     char *FUNC="DFGRIsetdims";
  1111.     if (ncomps == FAIL || (xdim<=0) || (ydim<=0)) {
  1112.         HERROR(DFE_ARGS);
  1113.         return FAIL;
  1114.     }
  1115.  
  1116.     Grwrite.datadesc[type].xdim = xdim;
  1117.     Grwrite.datadesc[type].ydim = ydim;
  1118.     Grwrite.datadesc[type].ncomponents = ncomps;
  1119.  
  1120.     Ref.dims[type] = 0;
  1121.  
  1122.     return SUCCEED;
  1123. }
  1124.  
  1125. /*-----------------------------------------------------------------------------
  1126.  * Name:    DFGRIsetil
  1127.  * Purpose: set interlace of image/lut
  1128.  * Inputs:  il: interlace of lut
  1129.  *          type: LUT if lut, IMAGE if image
  1130.  * Returns: 0 on success, -1 on failure with DFerror set
  1131.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  1132.  * Invokes: none
  1133.  * Remarks: none
  1134.  *---------------------------------------------------------------------------*/
  1135.  
  1136. #ifdef PROTOTYPE
  1137. int DFGRIsetil(int il, int type)
  1138. #else
  1139. int DFGRIsetil(il, type)
  1140.     int il;
  1141.     int type;
  1142. #endif
  1143. {
  1144.     char *FUNC="DFGRIsetil";
  1145.     if (il == FAIL) {
  1146.         HERROR(DFE_ARGS);
  1147.         return FAIL;
  1148.     }
  1149.     Grwrite.datadesc[type].interlace = il;
  1150.  
  1151.     return SUCCEED;
  1152. }
  1153. /*-----------------------------------------------------------------------------
  1154.  * Name:    DFGRIrestart
  1155.  * Purpose: restart file
  1156.  * Inputs:
  1157.  * Returns: 0 on success, -1 on failure with DFerror set
  1158.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  1159.  * Invokes: none
  1160.  * Remarks: none
  1161.  *---------------------------------------------------------------------------*/
  1162. #ifdef PROTOTYPE
  1163. int DFGRIrestart(void)
  1164. #else
  1165. int DFGRIrestart()
  1166. #endif
  1167. {
  1168.     Grlastfile[0] = '\0';
  1169.     Grrefset = 0;
  1170.     return SUCCEED;
  1171. }
  1172.  
  1173.  
  1174. /*-----------------------------------------------------------------------------
  1175.  * Name:    DFGRIaddimlut
  1176.  * Purpose: Internal routine to write RIG to file
  1177.  * Inputs:  filename: name of HDF file
  1178.  *          imlut: image/lut to be written to file
  1179.  *          xdim, ydim: dimensions of image/lut
  1180.  *          type: LUT if lut, IMAGE if image
  1181.  *          isfortran: 0 if called from C, 1 if called from Fortran
  1182.  * Returns: 0 on success, -1 on failure with DFerror set
  1183.  * Users:   HDF systems programmers, DFGRaddimage, DFGRaddlut, DFGRsetlut
  1184.  * Invokes: DFGRIopen, DFclose, DFputelement, DFdup, DFGRaddrig, DFputcomp,
  1185.  *          DFIerr
  1186.  * Remarks: Creates both RIG and RI8/CI8 tags, to accomodate older programs
  1187.  *          LUT will be associated with image if set previously
  1188.  *---------------------------------------------------------------------------*/
  1189.  
  1190. /* shut lint up */
  1191. /* ARGSUSED */
  1192. #ifdef PROTOTYPE
  1193. int DFGRIaddimlut(char *filename, VOIDP imlut, int32 xdim, int32 ydim,
  1194.                  int type, int isfortran, int newfile)
  1195. #else
  1196. int DFGRIaddimlut(filename, imlut, xdim, ydim, type, isfortran,
  1197.                  newfile)
  1198.     char *filename;
  1199.     int32 xdim, ydim;
  1200.     VOIDP imlut;
  1201.     int type, isfortran, newfile;
  1202. #endif
  1203. {
  1204.     char *FUNC="DFGRIaddimlut";
  1205.     int32 file_id;
  1206.     uint16 wtag, wref;         /* tag of image/lut being written */
  1207.     uint8 *newlut;
  1208.     int32 lutsize;
  1209.     int is8bit;
  1210.     struct {
  1211.         uint16 xdim;
  1212.         uint16 ydim;
  1213.     } r8dims;
  1214.     uint8 *p;
  1215.  
  1216.     HEclear();
  1217.  
  1218.     if (0 != HDstrcmp(Grlastfile,filename)) {  /* if new file, reset dims */
  1219.       Grwrite.datadesc[type].xdim = xdim;
  1220.       Grwrite.datadesc[type].ydim = ydim;
  1221.       Ref.dims[type] = 0;                  /* indicate set & not written */
  1222.     }
  1223.     
  1224.     if ((Ref.dims[type] == 0
  1225.      && (xdim != Grwrite.datadesc[type].xdim
  1226.          || ydim != Grwrite.datadesc[type].ydim))
  1227.     || !imlut) {
  1228.       HERROR(DFE_ARGS);
  1229.       return FAIL;
  1230.     }
  1231.     
  1232.     /* if dims not set, set dimensions */
  1233.     if (Ref.dims[type] == FAIL)        
  1234.         if (DFGRIsetdims(xdim, ydim, 1, type) == FAIL)
  1235.             return FAIL;
  1236.  
  1237.     /* default: ncomps=1, il=0 */
  1238.     
  1239.     if ((type==LUT) && (filename==NULL)) { /* set call */
  1240.       if (Grlutdata) {
  1241.         HDfreespace(Grlutdata);
  1242.         Grlutdata = NULL;
  1243.       }
  1244.       Ref.lut = -1;
  1245.       if (imlut==NULL)
  1246.         return SUCCEED;
  1247.       lutsize = Grwrite.datadesc[LUT].xdim * Grwrite.datadesc[LUT].ydim
  1248.             * Grwrite.datadesc[LUT].ncomponents;
  1249.       Grlutdata = (uint8 *) HDgetspace((uint32)lutsize);
  1250.       HDmemcpy(Grlutdata, imlut, (int)lutsize);
  1251.       Ref.lut = 0;
  1252.       return SUCCEED;
  1253.     }
  1254.     
  1255.     file_id = DFGRIopen(filename, newfile ? DFACC_CREATE : DFACC_RDWR);
  1256.     if (file_id==(int32)NULL)
  1257.        return FAIL;
  1258.  
  1259.     wref = Hnewref(file_id);
  1260.     if (!wref)
  1261.        return(HDerr(file_id));
  1262.  
  1263.     wtag = (type==LUT) ? DFTAG_LUT : Grcompr ? DFTAG_CI : DFTAG_RI;
  1264.     Grwrite.data[type].tag = wtag;
  1265.  
  1266.     is8bit = (Grwrite.datadesc[IMAGE].ncomponents == 1);
  1267.  
  1268.     /* write out image/lut */
  1269.     if ((type==IMAGE) && Grcompr) {
  1270.         if (Grwrite.datadesc[IMAGE].ncomponents>1) {
  1271.             HERROR(DFE_UNSUPPORTED);
  1272.             return(HDerr(file_id));
  1273.         }
  1274.         lutsize = Grwrite.datadesc[LUT].xdim * Grwrite.datadesc[LUT].ydim *
  1275.            Grwrite.datadesc[LUT].ncomponents;
  1276.         if (Grcompr==DFTAG_IMC) {
  1277.             if (Grlutdata==NULL) {
  1278.                 HERROR(DFE_BADCALL);
  1279.                 return(HDerr(file_id));
  1280.             }
  1281.             newlut = (uint8 *) HDgetspace((uint32)lutsize);
  1282.         }
  1283.         if (DFputcomp(file_id, wtag, wref, (uint8*)imlut, xdim, ydim,
  1284.                      (uint8*)Grlutdata, (uint8*)newlut, Grcompr) == FAIL)
  1285.             return(HDerr(file_id));
  1286.     } else {                   /* image need not be compressed */
  1287.         if (Hputelement(file_id, wtag, wref, (uint8 *)imlut,
  1288.                        xdim*ydim*Grwrite.datadesc[type].ncomponents) == FAIL)
  1289.             return(HDerr(file_id));
  1290.     }
  1291.     Grwrite.data[type].ref = wref;
  1292.     Grwrite.aspectratio = (float32)1.0;
  1293.  
  1294.     wtag = (type==LUT) ? DFTAG_IP8 : Grcompr ?
  1295.        ((Grcompr==DFTAG_RLE) ? DFTAG_CI8 : DFTAG_II8) : DFTAG_RI8;
  1296.     /* Write out Raster-8 tags for those who want it */
  1297.     if (is8bit
  1298.        && (Hdupdd(file_id, wtag, wref, Grwrite.data[type].tag, wref) == FAIL))
  1299.         return(HDerr(file_id));
  1300.  
  1301.     if (type==IMAGE)
  1302.        Grwrite.datadesc[IMAGE].compr.tag = Grcompr;
  1303.  
  1304.     if (Grcompr==DFTAG_IMC) {
  1305.         if (Hputelement(file_id, DFTAG_LUT, wref, newlut, lutsize) == FAIL)
  1306.             return(HDerr(file_id));
  1307.         Ref.lut = wref;
  1308.     }
  1309.  
  1310.     if (DFGRaddrig(file_id, wref, &Grwrite) == FAIL) /* writes ID, NT */
  1311.         return(HDerr(file_id));
  1312.  
  1313.     if (is8bit) {
  1314.        /* put in Raster-8 stuff also, for those who want it */
  1315.         if ((Ref.lut>=0)
  1316.            && Hdupdd(file_id, DFTAG_IP8, wref, DFTAG_LUT, wref) == FAIL)
  1317.             return(HDerr(file_id));
  1318.         p = (uint8 *) &r8dims.xdim;
  1319.         UINT16ENCODE(p, Grwrite.datadesc[IMAGE].xdim);
  1320.         UINT16ENCODE(p, Grwrite.datadesc[IMAGE].ydim);
  1321.         if (Hputelement(file_id, DFTAG_ID8, wref, (uint8 *)&r8dims, (int32) 4)
  1322.            == FAIL)
  1323.             return(HDerr(file_id));
  1324.     }
  1325.  
  1326.     if (Grcompr==DFTAG_IMC) {
  1327.         Ref.lut = 0;
  1328.        HDfreespace(newlut);
  1329.         newlut = NULL;
  1330.     }
  1331.  
  1332.     Grlastref = wref;               /* remember ref written */
  1333.  
  1334.     wref = 0;                  /* don't know ref to write next */
  1335.  
  1336.     return(Hclose(file_id));
  1337. }
  1338.  
  1339. /*-----------------------------------------------------------------------------
  1340.  * Name:    DFGRlastref
  1341.  * Purpose: Return last ref written or read
  1342.  * Inputs:  none
  1343.  * Globals: Grlastref
  1344.  * Returns: ref on success
  1345.  * Users:   HDF users, utilities, other routines
  1346.  * Invokes: none
  1347.  * Method:  return Grlastref
  1348.  * Remarks: none
  1349.  *---------------------------------------------------------------------------*/
  1350.  
  1351. #ifdef PROTOTYPE
  1352. uint16 DFGRIlastref(void)
  1353. #else
  1354. uint16 DFGRIlastref()
  1355. #endif
  1356. {
  1357.     return((uint16) Grlastref);
  1358. }
  1359.  
  1360.